#ifndef DEBUG_H
#define DEBUG_H

#pragma once
#include <QString>
#include <QFileInfo>
#include<QPixmap>
#include<QIcon>
#include<QBuffer>


#include"base.qpb.h"
#include"file.qpb.h"
#include"friend.qpb.h"
#include"gateway.qpb.h"
#include"message_storage.qpb.h"
#include"message_transmit.qpb.h"
#include"notify.qpb.h"
#include"speech_recognition.qpb.h"
#include"user.qpb.h"

// 辅助打印⽇志的宏定义
static inline QString getFileName(const QString& path) {
    QFileInfo fileInfo(path);
    return fileInfo.fileName();
}
#define TAG QString("[%1:%2]").arg(getFileName(__FILE__),QString::number(__LINE__))
// 使⽤ .noquote() 设置 qDebug 针对字符串不输出 ""
#define LOG() qDebug().noquote() << TAG

////////////////////////////////////////////////////////
/// ⼯具函数
////////////////////////////////////////////////////////

// 根据 QByteArray 转成 QIcon
static inline QIcon makeIcon(const QByteArray& byteArray) {
    QPixmap pixmap;
    pixmap.loadFromData(byteArray);
    QIcon icon(pixmap);
    return icon;
}

// 获取到图⽚的⼆进制数据
static inline QByteArray loadImageToByteArray(const QString& fileName) {
    // 1. 加载为 QImage
    QImage image(fileName);
    if (image.isNull()) {
        LOG() << "图⽚⽆法加载!";
        return QByteArray();
    }
    // 2. 转换成 QPixmap
    QPixmap pixmap = QPixmap::fromImage(image);
    // 3. 获取图⽚类型, 是 png 还是 jpg 还是啥别的
    QFileInfo fileInfo(fileName);
    QString type = fileInfo.suffix();
    // 4. 进⾏转换
    QByteArray byteArray;
    QBuffer buffer(&byteArray);
    bool ok = false;
    if (type == "png") {
        // 此处的 save ⽀持 BMP, JPG, JPEG, PNG
        ok = pixmap.save(&buffer, "PNG");
    } else if (type == "jpg" || type == "jpeg") {
        ok = pixmap.save(&buffer, "JPG");
    } else if (type == "bmp") {
        ok = pixmap.save(&buffer, "BMP");
    } else {
        LOG() << "图⽚类型不⽀持!";
        return QByteArray();
    }
    if (!ok) {
        // 如果保存失败，返回空的字节数组
        return QByteArray();
    }
    return byteArray;
}

// 获取到⽂件的⼆进制内容
static inline QByteArray loadFileToByteArray(const QString& filename) {
    QFile file(filename);
    bool ok = file.open(QFile::ReadOnly);
    if (!ok) {
        LOG() << "⽂件读取失败!";
        return QByteArray();
    }
    QByteArray content = file.readAll();
    file.close();
    return content;
}

// 把⼆进制数据写⼊⽂件
static inline void writeByteArrayToFile(const QString& filename, const QByteArray& content) {
    QFile file(filename);
    bool ok = file.open(QFile::WriteOnly);
    if (!ok) {
        LOG() << "⽂件写⼊失败!";
        return;
    }
    file.write(content);
    file.flush();
    file.close();
    return;
}

// 把时间戳转成 01-01 18:00:00 这样的格式化时间
static inline QString formatTime(int64_t timestamp) {
    QDateTime dateTime = QDateTime::fromSecsSinceEpoch(static_cast<time_t>(timestamp));
    return dateTime.toString("MM-dd HH:mm:ss");
}

// 获取当前秒级时间戳
static inline int64_t getTime() {
    return QDateTime::currentSecsSinceEpoch();
}

// 构造⼀个 UserInfo
static inline lx::UserInfo makeUserInfo(int index, const QByteArray& avatar) {
    lx::UserInfo userInfo;
    userInfo.setUserId(QString::number(1000 + index));
    userInfo.setNickname("小明" + QString::number(index));
    userInfo.setDescription("生活如河，自己就是自己的船");
    userInfo.setPhone("18612345678");
    userInfo.setAvatar(avatar);
    return userInfo;
}

static inline lx::UserInfo makeEmptyUserInfo(const QByteArray& avatar) {
    lx::UserInfo userInfo;
    userInfo.setUserId("");
    userInfo.setNickname("");
    userInfo.setDescription("");
    userInfo.setPhone("");
    userInfo.setAvatar(avatar);
    return userInfo;
}

// 构造⼀个⽂本消息对象
static inline lx::MessageInfo makeMessageInfo(int index, const QString& chatSessionId, const QByteArray& avatar) {
    lx::MessageInfo messageInfo;
    messageInfo.setChatSessionId(chatSessionId);
    messageInfo.setTimestamp(QDateTime::currentMSecsSinceEpoch() / 1000);
    messageInfo.setMessageId(QString::number(3000 + index));
    lx::UserInfo sender = makeUserInfo(index, avatar);
    messageInfo.setSender(sender);
    lx::MessageContent messageContent;
    messageContent.setMessageType(lx::MessageTypeGadget::MessageType::STRING);
    lx::StringMessageInfo stringMessageInfo;
    stringMessageInfo.setContent("这是⼀条消息" + QString::number(index) + ", " + chatSessionId);
    messageContent.setStringMessage(stringMessageInfo);
    messageInfo.setMessage(messageContent);
    return messageInfo;
}


static inline lx::MessageInfo makeEmptyMessageInfo(const QString& chatSessionId, const
                                     QByteArray& avatar) {
    lx::MessageInfo messageInfo;
    messageInfo.setChatSessionId(chatSessionId);
    messageInfo.setTimestamp(QDateTime::currentMSecsSinceEpoch() / 1000);
    messageInfo.setMessageId("");
    lx::UserInfo sender = makeEmptyUserInfo(avatar);
    messageInfo.setSender(sender);
    lx::MessageContent messageContent;
    messageContent.setMessageType(lx::MessageTypeGadget::MessageType::STRING);
    lx::StringMessageInfo stringMessageInfo;
    stringMessageInfo.setContent("");
    messageContent.setStringMessage(stringMessageInfo);
    messageInfo.setMessage(messageContent);
    return messageInfo;
}


// 测试 UI , 显⽰构造的假数据
#define TEST_UI 1
// 测试群组会话详情窗⼝
#define TEST_GROUP_SESSION_DETAIL 1
// 测试跳过登录窗⼝
#define TEST_SKIP_LOGIN 1
// 测试⽹络连通性
#define TEST_NETWORK 1
// 从⽹络获取数据
#define LOAD_DATA_FROM_NETWORK 1
// 是否连接测试服务器
#define CONNECT_TEST_SERVER 1

#endif // DEBUG_H
